<?php
// +----------------------------------------------------------------------
// | ZGUAN [ 致力于帮助更多的中小企业物联网转型 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.zguan.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ZGUAN 并不是自由软件，未经许可不能去掉ZGUAN 相关版权
// +----------------------------------------------------------------------
// | Author: ZGUAN Team <admin@zguan.cn>  0769-82282996  15899929162
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace app\http\middleware\api;

use app\common\repositories\users\UsersRepository;
use app\common\services\JwtService;
use app\exception\ApiException;
use app\http\response\api\StatusCode;
use app\Request;

class CheckToken
{

    public function handle(Request $request, \Closure $next, $force = true)
    {
        /** @var UsersRepository $usersRepository */
        $usersRepository = app()->make(UsersRepository::class);
        try {
            $token = $request->header('token');
            if (!$token || strlen($token) != 40) {
                throw new ApiException('token错误', StatusCode::LOGIN_CODE);
            }
            $jwtToken = $usersRepository->getToken($token);
            if (!$jwtToken) {
                throw new ApiException('token错误', StatusCode::LOGIN_CODE);
            }
            $service = new JwtService();
            $payload = $service->decode($jwtToken);
            if (!$payload) {
                throw new ApiException('token错误', StatusCode::LOGIN_CODE);
            }
            $userId = $payload->jti[0];
            $userInfo = $usersRepository->get($userId);
            if (!$userInfo) {
                throw new ApiException('用户不存在', StatusCode::LOGIN_CODE);
            }
            if ($userInfo['status'] != 1) {
                throw new ApiException('账号已被禁用', StatusCode::LOGIN_CODE);
            }
            $usersRepository->updateToken($token);
        } catch (\Exception $e) {
            if ($force) {
                throw  $e;
            }
            $request->macro('isLogin', function () {
                return false;
            });
            $request->macros(['userId', 'userInfo'], function () {
                return null;
            });
            return $next($request);
        }
        $request->macro('isLogin', function () {
            return true;
        });
        # 用户信息
        $request->macro('userInfo', function () use (&$userInfo) {
            return $userInfo;
        });
        # 用户ID
        $request->macro('userId', function () use (&$userInfo) {
            return $userInfo['id'];
        });
        return $next($request);
    }
}